package com.pureut.order.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.order.domain.ProcurementPlan;
import com.pureut.order.domain.ProcurementPlanBack;
import com.pureut.order.domain.ProcurementPlanDetail;
import com.pureut.order.domain.system.domain.MaterialAccessories;
import com.pureut.order.domain.system.domain.MaterialAwmateria;
import com.pureut.order.dto.ProcurementPlanDetailDto;
import com.pureut.order.dto.ProcurementPlanDetailViewDto;
import com.pureut.order.dto.ProcurementPlanDto;
import com.pureut.order.mapper.ProcurementPlanDetailMapper;
import com.pureut.order.mapper.ProcurementPlanMapper;
import com.pureut.order.service.ProcurementPlanBackService;
import com.pureut.order.service.ProcurementPlanDetailService;
import com.pureut.order.service.ProcurementPlanService;
import com.pureut.order.vo.PlanReleaseVo;
import com.pureut.order.vo.PlanVo;
import com.pureut.order.vo.ProcurementPlanDetailVo;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.domain.SysDictData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ProcurementPlanDetailServiceImpl extends ServiceImpl<ProcurementPlanDetailMapper, ProcurementPlanDetail> implements ProcurementPlanDetailService {

    @Resource
    ProcurementPlanDetailMapper procurementPlanDetailMapper;

    @Resource
    ProcurementPlanMapper procurementPlanMapper;

    @Resource
    ProcurementPlanService procurementPlanService;

    @Resource
    ProcurementPlanBackService procurementPlanBackService;

    @Resource
    FeignService feignService;


    /**
     * 采购订单明细列表
     *
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<ProcurementPlanDetailDto> getList(ProcurementPlanDetailVo procurementPlanDetailVo) {
        List<ProcurementPlanDetailDto> detailList = procurementPlanDetailMapper.getDetailList(procurementPlanDetailVo);
        //获取采购计划明细状态缓存字典数据
        List<SysDictData> statusArray = DictUtils.getDictCache("detail_status");
        Map<String, String> actualMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //单位
        List<SysDictData> materialUnitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> materialUnitMap = materialUnitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (ProcurementPlanDetailDto entity : detailList) {

            entity.setUnitDict(materialUnitMap.get(entity.getUnit()));

            entity.setStatusDict(actualMap.get(entity.getStatus()));
        }
        return detailList;
    }

    /**
     * 计划下达
     *
     * @param planReleaseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean planRelease(PlanReleaseVo planReleaseVo) throws Exception {
        List<PlanVo> planList = planReleaseVo.getPlanList();
        if (planList.size() == 1) {
            PlanVo planVo = planList.get(0);
            //修改计划单状态
            ProcurementPlan procurementPlan = procurementPlanService.getById(planVo.getPlanId());
            if (procurementPlan.getStatus() != 1 && procurementPlan.getStatus() != 8) {
                throw new GlobalException("只能操作待下达或者下达中的单据");
            }
            //获取该计划单已经下达的重量
//            List<ProcurementPlanBack> procurementPlanBacks = procurementPlanBackMapper.selectList(new QueryWrapper<ProcurementPlanBack>().lambda().eq(ProcurementPlanBack::getPlanId, procurementPlan.getId()));
//            BigDecimal bigDecimal = new BigDecimal(0);
//            for (ProcurementPlanBack entity : procurementPlanBacks) {
//                bigDecimal = bigDecimal.add(new BigDecimal(entity.getLowerWeight()));
//            }
//            //计划重量减去已经下达的重量，然后再和下达重量进行比较
//            BigDecimal subtract = new BigDecimal(procurementPlan.getPlanWeight()).subtract(bigDecimal);
//            if (Integer.parseInt(planVo.getLowerWeight()) >= Integer.parseInt(subtract.toString())) {
//                procurementPlan.setStatus(3);
//            } else {
//                procurementPlan.setStatus(8);
//            }

            BigDecimal surplusNum;
            if (procurementPlan.getSurplusNum() == null) {
                surplusNum = new BigDecimal(procurementPlan.getPlanWeight()).subtract(new BigDecimal(planVo.getLowerWeight()));
            } else {
                surplusNum = new BigDecimal(procurementPlan.getSurplusNum()).subtract(new BigDecimal(planVo.getLowerWeight()));
            }
            if (Integer.parseInt(surplusNum.toString()) > 0) {
                procurementPlan.setStatus(8);
            } else {
                procurementPlan.setStatus(3);
            }
            procurementPlan.setSurplusNum(surplusNum.toString());

            if (Integer.parseInt(planReleaseVo.getLowerWeightTotal()) >= Integer.parseInt(planVo.getLowerWeight())) {
                procurementPlan.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
                procurementPlanService.updateById(procurementPlan);
            } else {
                throw new GlobalException("下达总重量应大于等于分重量之和");
            }

            //保存明细数据
            ProcurementPlanDetail procurementPlanDetail = new ProcurementPlanDetail();
            procurementPlanDetail.setMaterialCode(procurementPlan.getMaterialCode());
            procurementPlanDetail.setDeptId(SecurityUtils.getDeptId());
            procurementPlanDetail.setCreateBy(SecurityUtils.getUsername());
            procurementPlanDetail.setCreateTime(new Date());
            procurementPlanDetail.setLowerWeight(String.valueOf(planVo.getLowerWeight()));
            procurementPlanDetail.setPlanWeight(procurementPlan.getPlanWeight());
            procurementPlanDetail.setStatus(1);
//            String authorityCoding = feignService.getAuthorityCoding("order:purchase:plan:detaillist");
            String cgjh = feignService.splitList("CGJH");
//            if (authorityCoding == null) {
//                throw new GlobalException("未进行单据配置,单据编码生成失败");
//            }
            procurementPlanDetail.setPurchasementNum(cgjh);
            procurementPlanDetail.setMaterialId(procurementPlan.getMaterialId());
            procurementPlanDetail.setDemandTime(procurementPlan.getDemandTime());
            procurementPlanDetail.setMaterialCategory(procurementPlan.getMaterialCategory());
            procurementPlanDetail.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
            procurementPlanDetail.setQualityStandard(Integer.parseInt(procurementPlan.getQualityStandard()));
            save(procurementPlanDetail);
            //保存采购计划撤回信息
            ProcurementPlanBack procurementPlanBack = new ProcurementPlanBack();
            procurementPlanBack.setLowerWeight(planVo.getLowerWeight());
            procurementPlanBack.setPlanId(planVo.getPlanId());
            procurementPlanBack.setDetailId(procurementPlanDetail.getId());
            return procurementPlanBackService.save(procurementPlanBack);

        } else if (planList.size() > 1) {
            //判断列表中物料编码是否一致（因为不同物料编码必然不同）
            StringBuilder ids = new StringBuilder();
            for (PlanVo plan : planList) {
                ids.append(plan.getPlanId()).append(",");
            }
            ids.deleteCharAt(ids.length() - 1);
            String s = ids.toString();
            List<ProcurementPlan> procurementPlans = procurementPlanMapper.selectList(new QueryWrapper<ProcurementPlan>().lambda().in(ProcurementPlan::getId, s));
            for (ProcurementPlan entity : procurementPlans) {
                if (entity.getStatus() != 1 && entity.getStatus() != 8) {
                    throw new GlobalException("存在状态不为待下达或者下达中的单据");
                }
            }
            //获取到列表中物料编码
            List<ProcurementPlanDetailViewDto> procurementPlanDetailViewDtos = planReleaseView(s);

            String materialCode = procurementPlanDetailViewDtos.get(0).getMaterialCode();
            String materialCategory = procurementPlanDetailViewDtos.get(0).getMaterialCategory();
            long materialId = procurementPlanDetailViewDtos.get(0).getMaterialId();
            int qualityStandard = procurementPlanDetailViewDtos.get(0).getQualityStandard();
            boolean isIdentical = true;
            for (ProcurementPlanDetailViewDto entity : procurementPlanDetailViewDtos) {
                if (!(entity.getMaterialCode().equals(materialCode))) {
                    isIdentical = false;
                    break;
                }
                if (entity.getQualityStandard() != qualityStandard) {
                    isIdentical = false;
                    break;
                }
            }
            if (!isIdentical) {
                throw new GlobalException("您所选择的物料编码、名称、规格、质量标准不一致");
            }

            for (PlanVo plan : planList) {
                ProcurementPlan procurementPlan = procurementPlanService.getById(plan.getPlanId());
                //获取该计划单已经下达的重量
//                List<ProcurementPlanBack> procurementPlanBacks = procurementPlanBackMapper.selectList(new QueryWrapper<ProcurementPlanBack>().lambda().eq(ProcurementPlanBack::getPlanId, procurementPlan.getId()));
//                BigDecimal bigDecimal = new BigDecimal(0);
//                for (ProcurementPlanBack entity : procurementPlanBacks) {
//                    bigDecimal = bigDecimal.add(new BigDecimal(entity.getLowerWeight()));
//                }
//                //计划重量减去已经下达的重量，然后再和下达重量进行比较
//                BigDecimal subtract = new BigDecimal(procurementPlan.getPlanWeight()).subtract(bigDecimal);
//                if (Integer.parseInt(plan.getLowerWeight()) >= Integer.parseInt(subtract.toString())) {
//                    procurementPlan.setStatus(3);
//                } else {
//                    procurementPlan.setStatus(8);
//                }
                //获取该计划单剩余计划量

                BigDecimal surplusNum;
                if (procurementPlan.getSurplusNum() == null) {
                    surplusNum = new BigDecimal(procurementPlan.getPlanWeight()).subtract(new BigDecimal(plan.getLowerWeight()));
                } else {
                    surplusNum = new BigDecimal(procurementPlan.getSurplusNum()).subtract(new BigDecimal(plan.getLowerWeight()));
                }
                procurementPlan.setSurplusNum(surplusNum.toString());

                if (Integer.parseInt(surplusNum.toString()) > 0) {
                    procurementPlan.setStatus(8);
                } else {
                    procurementPlan.setStatus(3);
                }
                procurementPlan.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
                procurementPlanService.updateById(procurementPlan);
            }

            BigDecimal bigDecimal = new BigDecimal(0);
            for (ProcurementPlanDetailViewDto entity : procurementPlanDetailViewDtos) {
                bigDecimal = bigDecimal.add(new BigDecimal(entity.getPlanWeight()));
            }
            //生成单据明细数据
            ProcurementPlanDetail procurementPlanDetail = new ProcurementPlanDetail();
//            String authorityCoding = feignService.getAuthorityCoding("order:purchase:plan:detaillist");
//            if (authorityCoding == null) {
//                throw new GlobalException("未进行单据配置,单据编码生成失败");
//            }
            procurementPlanDetail.setPurchasementNum(feignService.splitList("CGJH"))
                    .setMaterialId(materialId)
                    .setMaterialCode(procurementPlans.get(0).getMaterialCode())
                    .setMaterialCategory(Integer.parseInt(materialCategory))
                    .setPlanWeight(bigDecimal.toString())
                    .setLowerWeight(planReleaseVo.getLowerWeightTotal())
                    .setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice())
                    .setDemandTime(planReleaseVo.getDemandTime())
                    .setStatus(1)
                    .setCreateBy(SecurityUtils.getUsername())
                    .setCreateTime(new Date())
                    .setQualityStandard(qualityStandard);
            save(procurementPlanDetail);
            //生成退回数据
            List<ProcurementPlanBack> procurementPlanBackList = new ArrayList<>();
            BigDecimal bigDecimal1 = new BigDecimal(0);
            for (PlanVo entity : planList) {
                ProcurementPlanBack procurementPlanBack = new ProcurementPlanBack();
                procurementPlanBack.setPlanId(entity.getPlanId());
                procurementPlanBack.setDetailId(procurementPlanDetail.getId());
                procurementPlanBack.setLowerWeight(entity.getLowerWeight());
                procurementPlanBackList.add(procurementPlanBack);
                bigDecimal1 = bigDecimal1.add(new BigDecimal(String.valueOf(entity.getLowerWeight())));
            }
            if (Integer.parseInt(planReleaseVo.getLowerWeightTotal()) >= Integer.parseInt(bigDecimal1.toString())) {
                return procurementPlanBackService.saveBatch(procurementPlanBackList);
            } else {
                throw new GlobalException("下达总重量应大于等于分重量之和");
            }
        } else {
            throw new GlobalException("请至少勾选一条数据");
        }
    }

    /**
     * 计划下达回显
     *
     * @param ids
     * @return
     */
    @Override
    public List<ProcurementPlanDetailViewDto> planReleaseView(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        if (idList.size() == 0) {
            throw new GlobalException("请至少选择一条数据");
        }
        List<ProcurementPlanDto> procurementPlanListByIds = procurementPlanMapper.getProcurementPlanListByIds(idList);
        List<ProcurementPlanDetailViewDto> procurementPlanDetailViewDtos = new ArrayList<>();
        //单位
        List<SysDictData> materialUnitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> materialUnitMap = materialUnitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (ProcurementPlanDto entity : procurementPlanListByIds) {
            ProcurementPlanDetailViewDto procurementPlanDetailViewDto = new ProcurementPlanDetailViewDto();
            procurementPlanDetailViewDto.setMaterialName(entity.getMaterialName());
            procurementPlanDetailViewDto.setMaterialSpec(entity.getMaterialSpec());
            procurementPlanDetailViewDto.setMaterialCode(entity.getMaterialCode());
            procurementPlanDetailViewDto.setUnit(String.valueOf(entity.getUnit()));
            procurementPlanDetailViewDto.setUnitDict(materialUnitMap.get(String.valueOf(entity.getUnit())));
//            //如果是原料
//            if (1 == entity.getMaterialCategory()) {
//                AjaxResult awmateriaInfo = feignService.getAwmateriaInfo(procurementPlanDetailViewDto.getMaterialId());
//                MaterialAwmateria awmDetailed = JSON.parseObject(JSON.toJSONString(awmateriaInfo.get("data")), MaterialAwmateria.class);
//                procurementPlanDetailViewDto.setMaterialName(awmDetailed.getMaterialName());
//                procurementPlanDetailViewDto.setMaterialSpec(awmDetailed.getMaterialSpec());
//                procurementPlanDetailViewDto.setMaterialCode(awmDetailed.getMaterialCode());
//                procurementPlanDetailViewDto.setUnit(String.valueOf(awmDetailed.getMaterialUnit()));
//                procurementPlanDetailViewDto.setUnitDict(materialUnitMap.get(String.valueOf(awmDetailed.getMaterialUnit())));
//            }
//            //如果是辅料
//            if (2 == entity.getMaterialCategory()) {
//                AjaxResult accessoriesInfo = feignService.getAccessoriesInfo(procurementPlanDetailViewDto.getMaterialId());
//                MaterialAwmateria accDetailed = JSON.parseObject(JSON.toJSONString(accessoriesInfo.get("data")), MaterialAwmateria.class);
//                procurementPlanDetailViewDto.setMaterialName(accDetailed.getMaterialName());
//                procurementPlanDetailViewDto.setMaterialSpec(accDetailed.getMaterialSpec());
//                procurementPlanDetailViewDto.setMaterialCode(accDetailed.getMaterialCode());
//                procurementPlanDetailViewDto.setUnit(String.valueOf(accDetailed.getMaterialUnit()));
//                procurementPlanDetailViewDto.setUnitDict(materialUnitMap.get(String.valueOf(accDetailed.getMaterialUnit())));
//            }
            procurementPlanDetailViewDto.setId(entity.getId());
            procurementPlanDetailViewDto.setPurchaseNum(entity.getPurchaseNum());
            procurementPlanDetailViewDto.setPlanWeight(entity.getPlanWeight());
            procurementPlanDetailViewDto.setMaterialId(entity.getMaterialId());
            procurementPlanDetailViewDto.setMaterialCategory(String.valueOf(entity.getMaterialCategory()));
            procurementPlanDetailViewDto.setQualityStandard(Integer.parseInt(entity.getQualityStandard()));
            procurementPlanDetailViewDtos.add(procurementPlanDetailViewDto);
        }
        return procurementPlanDetailViewDtos;
    }
}
